package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.product.domain.Product;
import com.spzx.product.domain.ProductDetails;
import com.spzx.product.domain.ProductSku;
import com.spzx.product.domain.SkuStock;
import com.spzx.product.mapper.*;
import com.spzx.product.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品 服务实现类
 * </p>
 *
 * @author Taeyang
 * @since 2025-04-17
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private ProductSkuMapper productSkuMapper;

    @Autowired
    private SkuStockMapper skuStockMapper;

    @Autowired
    private ProductDetailsMapper productDetailsMapper;

    /**
     * 查询商品列表
     *
     * @param product 查询条件
     * @return 查询结果
     */
    @Override
    public List<Product> selectProductList(Product product) {

        // 第一种 Lambda：表达式，N+1 查询问题、复杂SQL支持有限
        // List<Product> list = list(new LambdaQueryWrapper<Product>()
        //         .like(StringUtils.isNotNull(product.getName()), Product::getName, product.getName())
        //         .eq(StringUtils.isNotNull(product.getBrandId()), Product::getBrandId, product.getBrandId())
        //         .eq(StringUtils.isNotNull(product.getCategory1Id()), Product::getCategory1Id, product.getCategory1Id())
        //         .eq(StringUtils.isNotNull(product.getCategory2Id()), Product::getCategory2Id, product.getCategory2Id())
        //         .eq(StringUtils.isNotNull(product.getCategory3Id()), Product::getCategory3Id, product.getCategory3Id())
        // );
        // if (StringUtils.isNotNull(list)) {
        //     list.forEach(item -> {
        //         item.setBrandName(brandMapper.selectBrandById(item.getBrandId()).getName());
        //         item.setCategory1Name(categoryMapper.selectById(item.getCategory1Id()).getName());
        //         item.setCategory2Name(categoryMapper.selectById(item.getCategory2Id()).getName());
        //         item.setCategory3Name(categoryMapper.selectById(item.getCategory3Id()).getName());
        //     });
        // }
        // return list;

        // 第二种 XML编写SQL
        return productMapper.selectProductList(product);
    }

    /**
     * 新增商品
     *
     * @param product 商品信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertProduct(Product product) {

        // 保存商品信息到Product表
        save(product);

        // 获取前端传递的商品SKU
        AtomicInteger i = new AtomicInteger();
        product.getProductSkuList().forEach(productSku -> {

            // 添加商品SKU信息
            productSku.setSkuCode(product.getId() + "_" + i.getAndIncrement());
            productSku.setProductId(product.getId());
            productSku.setSkuName(product.getName() + " " + productSku.getSkuSpec());
            productSkuMapper.insert(productSku);

            // 添加商品库存信息（需要先添加商品SKU信息之后才会有id，然后根据商品SKU去添加当前SKU的库存信息）
            SkuStock skuStock = new SkuStock();
            skuStock.setSkuId(productSku.getId());
            skuStock.setTotalNum(productSku.getStockNum());
            skuStock.setLockNum(0);
            skuStock.setAvailableNum(productSku.getStockNum());
            skuStock.setSaleNum(0);
            skuStockMapper.insert(skuStock);

        });

        // 添加商品详细信息
        ProductDetails productDetails = new ProductDetails();
        productDetails.setProductId(product.getId());
        productDetails.setImageUrls(String.join(",", product.getDetailsImageUrlList()));
        productDetailsMapper.insert(productDetails);

        // 返回商品的id
        return product.getId().intValue();
    }

    /**
     * 获取商品详细信息
     *
     * @param id 商品id
     * @return 商品信息
     */
    @Override
    public Product selectProductById(Long id) {

        // 商品基础信息
        Product product = getById(id);

        // 查询商品SKU列表
        List<ProductSku> productSkuList = productSkuMapper.selectList(new LambdaQueryWrapper<ProductSku>().eq(ProductSku::getProductId, id));

        // 查询商品库存
        // 提取SKU列表中每行数据的id收集为一个List
        List<Long> skuIdList = productSkuList.stream().map(ProductSku::getId).collect(Collectors.toList());
        // 根据SKU数据的id从库存表中查询每一个SKU的库存
        List<SkuStock> skuStockList = skuStockMapper.selectList(new LambdaQueryWrapper<SkuStock>().in(SkuStock::getSkuId, skuIdList).select(SkuStock::getSkuId, SkuStock::getTotalNum));
        // 将List转换为Map
        Map<Long, Integer> skuIdToStockNumMap = skuStockList.stream().collect(Collectors.toMap(SkuStock::getSkuId, SkuStock::getTotalNum));
        // 为商品不同的SKU设置库存
        productSkuList.forEach(item -> {
            item.setStockNum(skuIdToStockNumMap.get(item.getId()));
        });
        // 将商品SKU拼装到商品详细信息对象上
        product.setProductSkuList(productSkuList);

        // 查询商品详情
        ProductDetails productDetails = productDetailsMapper.selectOne(new LambdaQueryWrapper<ProductDetails>().eq(ProductDetails::getProductId, id));
        product.setDetailsImageUrlList(Arrays.asList(productDetails.getImageUrls().split(",")));

        return product;
    }

    /**
     * 修改商品信息
     *
     * @param product 商品信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateProduct(Product product) {

        // 修改商品基本信息
        updateById(product);

        product.getProductSkuList().forEach(productSku -> {
            // 修改商品SKU信息
            productSkuMapper.updateById(productSku);

            // 修改商品库存
            // 获取当前SKU的库存
            SkuStock skuStock = skuStockMapper.selectOne(new LambdaQueryWrapper<SkuStock>().eq(SkuStock::getSkuId, productSku.getId()));
            // 设置新库存数
            skuStock.setTotalNum(productSku.getStockNum());
            // 计算新可用库存数
            skuStock.setAvailableNum(skuStock.getTotalNum() - skuStock.getLockNum());
            // 提交修改
            skuStockMapper.updateById(skuStock);
        });

        // 修改商品详细信息
        // 最笨b的方法
        // ProductDetails productDetails = productDetailsMapper.selectOne(new LambdaQueryWrapper<ProductDetails>().eq(ProductDetails::getProductId, product.getId()));
        // productDetails.setImageUrls(String.join(",", product.getDetailsImageUrlList()));
        // productDetailsMapper.updateById(productDetails);

        // 新git的方法
        productDetailsMapper.update(
                new ProductDetails(),
                Wrappers.<ProductDetails>lambdaUpdate()
                        .set(ProductDetails::getImageUrls, String.join(",", product.getDetailsImageUrlList()))
                        .eq(ProductDetails::getProductId, product.getId())
        );

        // 老方法新写法
        // productDetailsMapper.update(
        //         new ProductDetails(),
        //         new LambdaUpdateWrapper<ProductDetails>()
        //                 .set(ProductDetails::getImageUrls, String.join(",", product.getDetailsImageUrlList()))
        //                 .eq(ProductDetails::getProductId, product.getId())
        // );

        return 1;
    }

    /**
     * 批量删除商品
     *
     * @param ids 要删除的商品主键合集
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delectProductByIds(Long... ids) {
        // 删除商品基础信息
        removeBatchByIds(Arrays.asList(ids));

        // 保留需要删除掉的SKU信息主键ID列表
        // 获取要从SKU表删除的数据的主键id
        List<ProductSku> productSkuList = productSkuMapper.selectList(
                Wrappers.<ProductSku>lambdaQuery()
                        .in(ProductSku::getProductId, Arrays.asList(ids))
                        .select(ProductSku::getId)
        );

        // TODO：后续开发时需要记得添加判断，当查询结果为空时会报异常

        // 整理成为Long类型的列表
        List<Long> skuIdList = productSkuList.stream().map(ProductSku::getId).collect(Collectors.toList());

        // 根据ids删除SKU
        productSkuMapper.delete(Wrappers.<ProductSku>lambdaQuery().in(ProductSku::getProductId, Arrays.asList(ids)));

        // 根据保留的已删除的SKU主键id列表删除库存信息
        skuStockMapper.delete(Wrappers.<SkuStock>lambdaQuery().in(SkuStock::getSkuId, skuIdList));

        // 根据ids删除详细信息
        productDetailsMapper.delete(Wrappers.<ProductDetails>lambdaQuery().in(ProductDetails::getProductId, Arrays.asList(ids)));

        return 1;
    }

    /**
     * 商品审核
     *
     * @param id          商品id
     * @param auditStatus 审核结果
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateAuditStatus(Long id, Integer auditStatus) {
        Product product = new Product();
        product.setId(id);
        if (auditStatus == 1) {
            product.setAuditStatus(1);
            product.setAuditMessage("审批通过");
        } else {
            product.setAuditStatus(-1);
            product.setAuditMessage("审批不通过");
        }
        return updateById(product) ? 1 : 0;
    }

    /**
     * 更新上下架状态
     *
     * @param id     商品id
     * @param status 状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Integer status) {
        update(Wrappers.<Product>lambdaUpdate().eq(Product::getId, id).set(Product::getStatus, status == 1 ? 1 : -1));
    }
}
